package com.nowcoder.community.controller;

import com.google.code.kaptcha.Producer;
import com.nowcoder.community.controller.exception.PageErrorException;
import com.nowcoder.community.dao.CommonRedisDao;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.entity.form.LoginForm;
import com.nowcoder.community.entity.form.RegisterForm;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;


@Controller
@Slf4j
public class AuthController {
    @Autowired
    UserService userService;

    @Autowired
    Producer captchaProducer;

    @Autowired
    CommonRedisDao commonRedisDao;

    @GetMapping("login")
    public String login(Model model) {
        model.addAttribute("captchaId", CommunityUtils.generateUUID());
        return "/site/login";
    }

    @PostMapping("login")
    public ModelAndView login(@Validated LoginForm form, String captchaId, BindingResult result) {
        ModelAndView ret = new ModelAndView("/site/login");
        ret.addObject("form", form);
        ret.addObject("captchaId", captchaId);
        if (result.hasFieldErrors()) {
            for (FieldError error : result.getFieldErrors()) {
                ret.addObject(error.getField().concat("Msg"), error.getDefaultMessage());
            }
            return ret;
        }

        String verifyCode = commonRedisDao.getCaptcha(captchaId);
        if(verifyCode == null) {
            ret.addObject("verifyCodeMsg", "验证码已过期.");
            return ret;
        }

        if (!Objects.equals(form.getVerifyCode(), verifyCode)) {
            ret.addObject("verifyCodeMsg", "请输入正确的验证码.");
            return ret;
        }

        ret = userService.login(new User(){{
            setPassword(form.getPassword());
            setUsername(form.getUsername());
        }}, form.isRememberMe()).addAllObjects(ret.getModel());
        return ret;
    }

    @GetMapping("logout")
    public ModelAndView logout(@CookieValue String ticket) {
        return userService.logout(ticket);
    }

    @GetMapping("register")
    public String registerPage(Model model){
        model.addAttribute("captchaId", CommunityUtils.generateUUID());
        return "/site/register";
    }

    @PostMapping("register")
    public ModelAndView register(@Validated RegisterForm form, String captchaId, BindingResult result) {
        ModelAndView ret = new ModelAndView("/site/register");
        ret.addObject("captchaId", captchaId);
        ret.addObject("form", form);

        if (result.hasFieldErrors()) {
            for (FieldError error : result.getFieldErrors()) {
                ret.addObject(error.getField().concat("Msg"), error.getDefaultMessage());
            }
            return ret;
        }

        String verifyCode = commonRedisDao.getCaptcha(captchaId);
        if(verifyCode == null) {
            ret.addObject("verifyCodeMsg", "验证码已过期.");
            return ret;
        }

        if (!Objects.equals(form.getVerifyCode(), verifyCode)) {
            ret.addObject("verifyCodeMsg", "请输入正确的验证码.");
            return ret;
        }

        ret = userService.register(new User() {
            {
                setUsername(form.getUsername());
                setPassword(form.getPassword());
                setEmail(form.getEmail());
            }
        }).addAllObjects(ret.getModel());
        return ret;
    }

    @GetMapping("activation/{userId}/{activationCode}")
    public ModelAndView active(@PathVariable int userId, @PathVariable String activationCode) {
        return userService.active(new User(){
            {setId(userId); setActivationCode(activationCode);}
        });
    }

    @GetMapping("captcha/{id}")
    public void getCaptcha(HttpServletResponse resp, @PathVariable String id) {
        if (id == null || id.isEmpty()) {
            throw new PageErrorException();
        }
        String text = captchaProducer.createText();
        commonRedisDao.setCaptcha(id, text, 120);
        resp.setContentType("image/png");
        try {
            OutputStream os = resp.getOutputStream();
            BufferedImage image = captchaProducer.createImage(text);
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            log.error("响应生成验证码失败: " + e.getMessage());
        }
    }
}
